<?php

namespace App\Repositories\Manage;

use App\Models\DailyMenu;
use App\Models\LouAddress;
use App\Models\MemberLabel;
use App\Models\Order;
use App\Models\OrderAddress;
use App\Models\OrderProduct;
use App\Models\OrderSku;
use App\Models\Park;
use App\Models\PrinterTask;
use App\Models\Supplier;
use App\Models\Wemch;
use App\Repositories\PrinterRepository;
use App\Repositories\WechatRepository;
use Exception;
use Illuminate\Support\Facades\Log;

class OrderRepository
{
    /**
     * 订单搜索原型
     * @param array $filter
     * @param array $extra_condition
     */
    private function _order_model($filter = [], $extra_condition = [])
    {
        $model = Order::from("order as o")
//            ->join("order_address as p", "p.order_id", "=", "o.id")
            ->join("member as m", "m.id", "=", "o.uid")
            ->join("supplier as s", "s.id", "=", "o.shop_id")
            ->join("daily_menu as d", "d.id", "=", "o.menu_id")
            ->when(!empty($filter['uid']), function ($query) use ($filter) {
                return $query->where("o.uid", "=", intval($filter['uid']));
            })
            ->when(!empty($filter['stype']), function ($query) use ($filter) {
                $uids = MemberLabel::query()->where(["type" => intval($filter['stype'])])->pluck("uid")->toArray();
                return $query->whereIn("uid", array_unique($uids));
            })
            ->when(!empty($filter['menu_id']), function ($query) use ($filter) {
                return $query->where("o.menu_id", "=", intval($filter['menu_id']));
            })
            ->when(!empty($filter['start_callNo']), function ($query) use ($filter) {
                return $query->where("o.callNo", ">", intval($filter['start_callNo']));
            })
            ->when(!empty($filter['end_callNo']), function ($query) use ($filter) {
                return $query->where("o.callNo", "<=", intval($filter['end_callNo']));
            })
            ->when(!empty($filter['out_trade_no']), function ($query) use ($filter) {
                return $query->where("o.out_trade_no", "like", "%{$filter['out_trade_no']}%")
                    ->OrWhere("o.out_trade_no", "like", "%{$filter['out_trade_no']}%");
            })
            ->when(!empty($filter['shop_id']), function ($q) use ($filter) {
                if (is_array($filter['shop_id'])) {
                    return $q->whereIn("o.shop_id", $filter['shop_id']);
                } else {
                    return $q->where("o.shop_id", $filter['shop_id']);
                }
            })
            ->when(!empty($filter['ids']), function ($query) use ($filter) {
                if (is_array($filter['ids'])) {
                    return $query->whereIn("o.id", $filter['ids']);
                } else {
                    return $query->where("o.id", "=", $filter['ids']);
                }
            })
            ->when(isset($filter['status']), function ($q) use ($filter) {
                if (is_array($filter['status'])) {
                    return $q->whereIn("o.status", $filter['status']);
                } else {
                    return $q->where("o.status", "=", intval($filter['status']));
                }
            })
            ->when(!empty($filter['deliver_status']), function ($q) use ($filter) {
                if (is_array($filter['deliver_status'])) {
                    return $q->whereIn("o.deliver_status", $filter['deliver_status']);
                } else {
                    return $q->where("o.deliver_status", $filter['deliver_status']);
                }
            })
            ->when((!empty($filter['delivery_status']) || strlen($filter['delivery_status']) == 1), function ($q) use ($filter) {
                if (is_array($filter['delivery_status'])) {
                    return $q->whereIn("o.delivery_status", $filter['delivery_status']);
                } else {
                    return $q->where("o.delivery_status", $filter['delivery_status']);
                }
            })
            ->where("o.is_delete", 2)
            ->whereNull("o.deleted_at")
            ->when(!empty($extra_condition['between']), function ($query) use ($extra_condition) {
                foreach ($extra_condition['between'] as $k => $v) {
                    $query->whereBetween($k, $v);
                }
            });

        if ($filter['shop_type'] == 0 && !empty($filter['deliver_time'])) {
            $model->where('delivery_start_time', '>=', $filter['deliver_time'][0] . ':00')
                ->where('delivery_end_time', '<=', $filter['deliver_time'][1] . ':00');
        }

        return $model;
    }

    public function getOrderIdsByFilter($filter = [], $extra_condition = [])
    {
        $res = $this->_order_model($filter, $extra_condition)
            ->join("order_address as oa", "oa.order_id", "=", "o.id")
            ->join("lou_address as l", "l.id", "=", "oa.province_id")
            ->join("lou_address as la", "la.id", "=", "oa.city_id")
            ->join("lou_address as lr", "lr.id", "=", "oa.region_id")
            ->whereNull("s.deleted_at")
//            ->whereIn("oa.order_id", $orderIds)
            ->orderBy("l.sort", "asc")
            ->orderBy("la.sort", "asc")
//            ->orderBy("o.id", "desc")
            ->get(array_filter(explode(",", "o.*,s.title as shop_title,oa.phone,oa.consignee,oa.district,oa.address,l.title as province_title,la.title as city_title,lr.title as region_title")))
            ->toArray();

        foreach ($res as $k => &$v) {
            $v['current_status'] = $this->getStatus($v);
            if (isset($v['store_time']))
                $v['store_time'] = json_decode($v['store_time'], true);

            if ($v['shop_type'] == 0) {
                $v['deliver_time'] = $v['delivery_date'] . ' ' . substr($v['delivery_start_time'], 0, 5) . '-' . substr($v['delivery_end_time'], 0, 5);
            } else {
                $v['deliver_time'] = substr($v['mealtime'], 0, 16);
            }

            //菜单
            if (isset($v['menu_id'])) {
                $v['menu_title'] = $v['delivery_date'] . ' ' . menu_type($v['menu_type']);
            }
            $v['products'] = $this->getOrderProductList($v['id']);

            is_numeric($v['city_title']) && $v['city_title'] .= 'F';
            is_numeric($v['province_title']) && $v['province_title'] .= '号楼';
        }

        return $res;
    }

    public function getList($filter = [], $pageNum = 1, $pageSize = 10, $extra_condition = []): array
    {
        if ($filter['deliver_time']) { //配送时间格式化
            $deliver_time = deliver_timeList($filter['deliver_time']);
            if ($deliver_time) {
                $deliver_time = array_filter(explode("-", $deliver_time));
            }
            $filter['deliver_time'] = $deliver_time;
        }

        $field = ["o.*", 's.title as shop_title', 'd.type as menu_type', 'd.date as menu_date'];
//        sql(false);
        $res = $this->_order_model($filter, $extra_condition)
            ->whereNull("s.deleted_at")
            ->orderBy("id", "desc")
            ->paginate($pageSize, $field, null, $pageNum)
            ->toArray();

        $res = filterPaginateData($res);
        foreach ($res['items'] as $k => &$v) {
            $v['current_status'] = $this->getStatus($v);
            if (isset($v['park_id']))
                $v['park_title'] = Park::query()->where("id", $v['park_id'])->value("title");

            if (isset($v['store_time']))
                $v['store_time'] = json_decode($v['store_time'], true);

            $v['address'] = $this->getOrderAddressByOrderId($v['id']);
            $v['products'] = $this->getOrderProductList($v['id']);

            //菜单
            if (isset($v['menu_id'])) {
                $menu = DailyMenu::query()->where([
                    "id" => $v['menu_id'],
                    "is_delete" => 2,
                ])->first(['id', "type", "date"]);

                $v['menu_title'] = $menu['date'] . ' ' . menu_type($menu['type']);
            }

            if ($v['shop_type'] == 0) {
                $v['deliver_time'] = $v['delivery_date'] . ' ' . substr($v['delivery_start_time'], 0, 5) . '-' . substr($v['delivery_end_time'], 0, 5);
            }
        }

        return $res;
    }

    /**
     * 订单地址
     * @param int $orderId
     */
    public function getOrderAddressByOrderId(int $orderId = 0)
    {
        if (!$orderId)
            return null;

        $redis_key = "orderAddress_" . $orderId;
        $res = getRedisByKey($redis_key);

        if (isset($res))
            return $res;

        $res = OrderAddress::query()
            ->with(["province" => function ($query) {
                return $query->select(["id", "title"]);
            }])
            ->with(["city" => function ($query) {
                return $query->select(["id", "title"]);
            }])
            ->with(["region" => function ($query) {
                return $query->select(["id", "title"]);
            }])
            ->where("order_id", $orderId)
            ->first();

        if (isset($res['province'])) {
            $res['province_title'] = $res['province']['title'] ?? "";
            unset($res['province']);

            is_numeric($res['province_title']) && $res['province_title'] .= '号楼';
        }

        if (isset($res['city'])) {
            $res['city_title'] = $res['city']['title'] ?? "";
            is_numeric($res['city_title']) && $res['city_title'] .= 'F';
            unset($res['city']);
        }

        if (isset($res['region'])) {
            $res['region_title'] = $res['region']['title'] ?? "";
            unset($res['region']);
        }

        if (isset($res['district'])) {
            $res['district_title'] = $res['district']['title'] ?? "";
            unset($res['district']);
        }

        if (empty($res))
            return null;

        setRedisByDb($redis_key, $res);
        return $res ?? null;
    }

    public function getByOutTradeNo($outTradeNo = null)
    {
        if (empty($outTradeNo))
            return null;

        $res = Order::query()->where(["out_trade_no" => $outTradeNo, 'is_delete' => 2])->first();

        if ($res['shop_type'] == 0) {
            $res['deliver_time'] = $res['delivery_date'] . ' ' . substr($res['delivery_start_time'], 0, 5) . '-' . substr($res['delivery_end_time'], 0, 5);
        }

        return $res;
    }

    public function getOne($id = null)
    {
        $res = Order::query()->where(["id" => $id, 'is_delete' => 2])->first();

        if (!isset($res))
            return null;

        if (isset($res['store_time']))
            $res['store_time'] = json_decode($res['store_time'], true);

        $res['products'] = $this->getOrderProductList($id);
        $res['address'] = $this->getOrderAddressByOrderId($id);
        if ($res['menu_id']) {
            $menu = DailyMenu::query()->where(['id' => $res['menu_id']])->first();
            if ($menu) {
                $res['menu_title'] = $menu['date'] . ' ' . menu_type($menu['type']);
                $res['deliver_time'] = $menu['deliver_time'] ?? "";
            }
        }

        $res['current_status'] = $this->getStatus($res);
        $res['shop'] = (new  SupplierRepository())->getOne($res['shop_id']);

        //付款时间
        $res['pay_time'] && $res['pay_time'] = date("Y-m-d H:i:s", $res['pay_time']);

        $res['total_price'] = formatNum($res['total_price']);
        $res['refund_price'] = formatNum($res['refund_price']);
        $res['fact_price'] = formatNum($res['fact_price']);
        $res['coupon_price'] = formatNum($res['coupon_price']);
        $res['express_price'] = formatNum($res['express_price']);
        $res['total_product_price'] = $res['total_price'] - $res['express_price'] - $res['bag_price'];

        if ($res['shop_type'] == 0) {
            $res['deliver_time'] = $res['delivery_date'] . ' ' . substr($res['delivery_start_time'], 0, 5) . '-' . substr($res['delivery_end_time'], 0, 5);
        } else {
            $res['deliver_time'] = DailyMenu::query()->where('id', $res['menu_id'])->value("deliver_time");
        }

        return $res;
    }

    public function saveOrUpdate($data = [], $id = 0)
    {
        if (!empty($data['id']))
            unset($data['id']);

        if (intval($id)) {
            Order::where("id", $id)->update($data);
            return $id;
        } else {
            $res = Order::create($data);
            return $res['id'] ?? "";
        }
    }

    /**
     * 删除
     * @param null $id
     */
    public function deleteOrder($id = null)
    {
        if (!intval($id))
            return retFail("参数错误");

        Order::where(['id' => intval($id)])->delete();

        return retSuc([], "删除成功");
    }

    /**
     * 订单产品
     * @param int $order_id
     */
    public function getOrderProductList($order_id = 0)
    {
        $redis_key = "orderProductList_" . $order_id;
        $goodsList = getRedisByKey($redis_key);

        if (!empty($goodsList))
            return $goodsList;

        $goodsList = OrderProduct::query()->where(['order_id' => $order_id])
            ->get(array_filter(explode(",", "id,spec_type,product_title,product_title as title,amount,type,product_id,product_price,thumb,stall_id,order_id")));

        foreach ($goodsList as $k => &$v) {
            if ($v['type'] == 2) {//多规格
                $v['skus'] = OrderSku::query()
                    ->where(["order_product_id" => $v['id'], 'type' => 0])
                    ->orderBy("id", "asc")
                    ->get(['id', 'spec_item_id', 'spec_item_title', 'spec_price']);
                if ($v['skus']) {
                    $v['sku_txt'] = implode("、", get_column($v['skus'], "spec_item_title"));
                }
            } else if ($v['type'] == 1) { //套餐
                $v['skus'] = OrderSku::query()
                    ->where(["order_product_id" => $v['id'], 'type' => 1])
                    ->orderBy("sequence", "asc")
                    ->orderBy("id", "asc")
                    ->get(['id', 'goods_id', 'spec_id', 'spec_item_id', 'spec_item_title', 'amount', 'sequence']);
            }
        }

        setRedisByDb($redis_key, $goodsList ?? null);
        return $goodsList;
    }

    /**
     * 退款/取消
     */
    public function cancelOrder($out_trade_no = null, $data = [])
    {
        if (!intval($out_trade_no))
            return retFail("参数错误");

        $order = $this->getByOutTradeNo($out_trade_no);
        if (!in_array($order['status'], [10, 20])) {
            return retFail("订单不可退款");
        }

        //type 0:全额退款  1：部分退款
        if (intval($data['type'] ?? 0) == 1) {
            $refund_price = round($data['price'] ?? 0, 2);
            if ($refund_price > $order['total_price']) {
                return retFail("退款金额不能大于实付金额");
            }
            $pay_price = round($data['total_price'] - $refund_price，2);
        } else {
            $refund_price = round($order['total_price'], 2);
            $pay_price = round($order['total_price'], 2);
        }

        //取消日志
        Log::channel("ordercancel")->info(json_encode([
            'from' => "admin",
            'out_trade_no' => $order['out_trade_no'],
            'status' => $order['status'],
            'pay_price' => $pay_price,
            'deliver_status' => $order['deliver_status'],
            'delivery_status' => $order['delivery_status'],
            'active_uid' => UID,
            'action_time' => date("Y-m-d H:i:s")
        ]));

        // 代下单  只取消  不退款
        if ($order['order_source'] == 1) {
            Order::query()->where(['id' => $order['id']])
                ->update([
                    'status' => 80,
                    'refund_type' => 1,
                    'pay_price' => 0,
                    'refund_note' => $data['refund_note'] ?? "",
                    'refund_time' => date("Y-m-d H:i:s")
                ]);
            return retSuc([], "取消成功");
        }

        //判断是否要退款  是否在指定时间内取消订单
        $refund_data = [];
        $refund_data['transaction_id'] = $order['transaction_id'];
        $refund_data['total_fee'] = $pay_price;
        $refund_data['refund_fee'] = $refund_price;
        $refund_data['refund_no'] = $order['type'] . 'refund' . date('Ymdhis') . rand(1000, 9999);

        $config = null;
        if (!empty($order['mch_id'])) { //其他商户
            $wemch = Wemch::query()->where(['shop_id' => $order['shop_id'], 'mch_id' => $order['mch_id']])->first();
            if ($wemch) {
                $config = [
                    'mch_id' => trim($wemch['mch_id']),
                    'mch_secret' => trim($wemch['secret']),
                    'cert_path' => request()->server('DOCUMENT_ROOT') . $wemch['cert_path'],
                    'key_path' => request()->server('DOCUMENT_ROOT') . $wemch['key_path'],
                ];
            }
        }
        try {
            $result = (new WechatRepository($config ?? null))->refund($refund_data);
            /* if ($result['result_code'] == "FAIL") {
                 return retFail("微信退款失败：" . $result['err_code_des']);
             }*/
        } catch (Exception $e) {
            return retFail($e->getMessage());
        }

        $order_data = [];
        if ($result["return_code"] == 'SUCCESS' && $result["result_code"] == 'SUCCESS') {
            $order_data["refund_status"] = 1;
            $order_data["refund_type"] = 1;
            $order_data['refund_id'] = $result["refund_id"];
            $order_data['refund_sn'] = $refund_data['refund_no'];
            $order_data['refund_price'] = $refund_data['refund_fee'];
            $order_data['refund_time'] = date("Y-m-d H:i:s");
            $order_data['pay_price'] = $pay_price;
            $order_data['refund_note'] = $data['refund_note'] ?? "";
            $order_data['status'] = 60;
            Order::query()->where("id", $order['id'])->update($order_data);
            return retSuc([], "退款成功，费用将原路退回");
        } else {
            $order_data["refund_status"] = 2;
            $order_data["refund_type"] = 1;
            $order_data['refund_id'] = $result["refund_id"] ?? "";
            $order_data["pay_price"] = 0;
            $order_data['status'] = 60;
            $order_data['refund_price'] = $refund_data['refund_fee'];
            $order_data['refund_note'] = $data['refund_note'] ?? "";

            if ($order_data['refund_error_message'] == "订单已全额退款") {
                Order::query()->where("id", $order['id'])->update($order_data);
                return retSuc([], "已成功取消，请不要重复操作！");
            }

            return retFail(trim($result["err_code_des"]));
        }
    }

    /**
     * 批量删除
     * @param null $ids
     */
    public function batchDelete($ids = null)
    {
        if (intval($ids)) {
            Order::query()->where(['id' => $ids])->update([
                'is_delete' => 1,
                'deleted_at' => date("Y-m-d H:i:s")
            ]);
        } else {
            Order::query()->whereIn("id", $ids)->update([
                'is_delete' => 1,
                'deleted_at' => date("Y-m-d H:i:s")
            ]);
        }

        return retSuc([], "删除成功");
    }

    /**
     * 获取订单状态值
     * @param $order
     */
    public function getStatus($order)
    {
        $status = $order['status'];
        if ($status == 10) {
            //配送状态
            if ($order['delivery_status'] == 20) {

                switch ($order['deliver_status']) {
                    case 4:  //配送完成
                        $status = 20;
                        break;
                    case 3:  //配送中
                        $status = 17;
                        break;
                    case 2: //待配送
                        $status = 16;
                        break;
                    default:
                        break;
                }
            } else if ($order['delivery_status'] == 10) {
                $status = 12; //出餐中
            } else {
                $status = 11; //待接单
            }
        }

        return $status;
    }

    /**
     * 状态映射
     * @param int $status
     * @return array
     */
    public function getStatMapping(int $status = 0)
    {
        if (!$status)
            return [];
        $filter = [];
        switch ($status) {
            case 11:
                $filter['status'] = 10;
                $filter['delivery_status'] = 0;
                break;
            case 12:
                $filter['status'] = 10;
                $filter['delivery_status'] = 10;
                break;
            case 17:
                $filter['status'] = 10;
                $filter['delivery_status'] = 20;
                $filter['deliver_status'] = 3;
                break;
            default:
                $filter['status'] = $status;
                break;
        }

        return $filter;
    }

//    统计数
    public function getStat($filter = [], $condition = [])
    {
        $status = $filter['status'] ?? [];
        unset($filter['status']);

        $ids = $filter['ids'] ?? null;

        if (!empty($filter['ids'])) {
            unset($filter['ids']);
        }
        if (!empty($filter['stype'])) {
            unset($filter['stype']);
        }

        return Order::query()->where($filter)
            ->when($status, function ($q) use ($status) {
                if (is_array($status)) {
                    return $q->whereIn("status", $status);
                } else {
                    return $q->where("status", $status);
                }
            })
            ->when(!empty($ids), function ($query) use ($ids) {
                if (is_array($ids)) {
                    $query->whereIn("id", $ids);
                } else {
                    $query->where("id", "=", $ids);
                }
            })
            ->when(!empty($condition['between']), function ($query) use ($condition) {
                foreach ($condition['between'] as $k => $v) {
                    $query->whereBetween(str_replace("o.", '', $k), $v);
                }
            })
            ->count("id");
    }


    /**
     * 产品搜索原型
     * @param $filter
     */
    private function _model_product($filter = [])
    {
        return OrderProduct::from("order_product as op")
            ->join("order as o", "o.id", "=", "op.order_id")
            ->join("stall as s", "s.id", "=", "op.stall_id")
            ->join("daily_menu as dm", "dm.id", "=", "o.menu_id")
            ->when(!empty($filter['menu_id']), function ($q) use ($filter) {
                if (is_array($filter['menu_id'])) {
                    return $q->whereIn("o.menu_id", $filter['menu_id']);
                } else {
                    return $q->where("o.menu_id", $filter['menu_id']);
                }
            })
            ->when(!empty($filter['ids']), function ($q) use ($filter) {
                if (is_array($filter['ids'])) {
                    $q->whereIn("o.id", $filter['ids']);
                } else {
                    $filter["ids"] = json_decode($filter['ids']);
                    $q->whereIn("o.id", $filter['ids']);
                }
            })
            ->when(!empty($filter['stall_id']), function ($q) use ($filter) {
                if (is_array($filter['stall_id'])) {
                    return $q->whereIn("op.stall_id", $filter['stall_id']);
                } else {
                    return $q->where("op.stall_id", $filter['stall_id']);
                }
            })
            ->when(!empty($filter['shop_id']), function ($q) use ($filter) {
                if (is_array($filter['shop_id'])) {
                    return $q->whereIn("s.shop_id", $filter['shop_id']);
                } else {
                    return $q->where("s.shop_id", $filter['shop_id']);
                }
            })
            ->when(!empty($filter['start_callNo']), function ($query) use ($filter) {
                return $query->where("o.callNo", ">", intval($filter['start_callNo']));
            })
            ->when(!empty($filter['end_callNo']), function ($query) use ($filter) {
                return $query->where("o.callNo", "<=", intval($filter['end_callNo']));
            })
            ->when(!empty($filter['out_trade_no']), function ($query) use ($filter) {
                return $query->where("o.out_trade_no", "like", "%{$filter['out_trade_no']}%")
                    ->OrWhere("o.out_trade_no", "like", "%{$filter['out_trade_no']}%");
            })
            ->when(isset($filter['status']), function ($q) use ($filter) {
                if (is_array($filter['status'])) {
                    return $q->whereIn("o.status", $filter['status']);
                } else {
                    return $q->where("o.status", "=", intval($filter['status']));
                }
            })
            ->when(!empty($filter['deliver_status']), function ($q) use ($filter) {
                if (is_array($filter['deliver_status'])) {
                    return $q->whereIn("o.deliver_status", $filter['deliver_status']);
                } else {
                    return $q->where("o.deliver_status", $filter['deliver_status']);
                }
            })
            ->when((!empty($filter['delivery_status']) || strlen($filter['delivery_status']) == 1), function ($q) use ($filter) {
                if (is_array($filter['delivery_status'])) {
                    return $q->whereIn("o.delivery_status", $filter['delivery_status']);
                } else {
                    return $q->where("o.delivery_status", $filter['delivery_status']);
                }
            })
            ->when(!empty($filter['between']), function ($query) use ($filter) {
                foreach ($filter['between'] as $k => $v) {
                    $query->whereBetween($k, $v);
                }
            })
            ->whereNull("o.deleted_at")
            ->where(['o.is_delete' => 2]);
    }

    /**
     * 档口统计
     * @param $filter
     */
    public function getOrderStallStat($filter = [], $condition = [])
    {
        $fields = "op.id,op.order_id,op.type,op.amount,op.product_id,op.product_title as title,op.stall_id,o.menu_id,s.title as stall_title,dm.date as menu_date,dm.type as menu_type";

        $orderProducts = $this->_model_product($filter)
            ->orderBy("op.stall_id", "ASC")
            ->orderBy("op.product_id", "ASC")
            ->orderBy("o.id", "DESC")
            ->get(array_filter(explode(",", $fields)))
            ->toArray();

        if (empty($orderProducts))
            return [];

        $shop_type = Supplier::query()->where("id", intval($filter['shop_id']))->value("type");
        $products = [];
        foreach ($orderProducts as $k => $v) {
            if ($v['type'] != 1) {
                $products[] = $v;
                continue;
            }

            //套餐总量计算
            $skus = (new \App\Repositories\OrderRepository())->getOrderSkusByOpid($v['id'], 1);
            foreach ($skus['skus'] as $sk => $sv) {
                $products[] = [
                    'order_id' => $v['order_id'],
                    'product_id' => $sv['item_product_id'],
                    'title' => $sv['spec_item_title'],
                    'amount' => intval($v['amount']) * intval($sv['amount']), //套餐 * 单品
                    'menu_id' => $v['menu_id'],
                    'menu_date' => $v['menu_date'],
                    'menu_type' => $v['menu_type'],
                    'stall_id' => $v['stall_id'],
                    'stall_title' => $v['stall_title'],
                    'combo_id' => $v['product_id'],
                    'skuTxt' => $skus['skuTxt'] ?? ""
                ];
            }
        }

        $orderProducts = ass_column($products, "stall_id", true);
        $orderStat = [];
        foreach ($orderProducts as $k => $v) {//档口
            $v = ass_column($v, "menu_id", true);

            foreach ($v as $sk => $sv) { //菜单
                $sv = ass_column($sv, "product_id", true);
                foreach ($sv as $ssk => $ssv) {
//                    $skus = (new \App\Repositories\OrderRepository())->getOrderSkus($ssv[0]['order_id'], $ssk, $ssv[0]['type']);
                    $orderStat[] = [
                        'stall_title' => $ssv[0]['stall_title'],
                        'stall_id' => $k,
                        'order_id' => $ssv[0]['order_id'],
                        'type' => $ssv[0]['type'],
                        'menu_id' => $sk,
                        'menu_title' => $shop_type == 1 ? ($ssv[0]['menu_date'] . menu_type($ssv[0]['menu_type'])) : '普通',
                        'product_title' => $ssv[0]['title'],
                        'skuTxt' => $ssv[0]['skuTxt'] ?? "",
//                        'skuTxt' => $skus ? $skus['skuTxt'] : '',
                        'amount' => array_sum(get_column($ssv, "amount")),
                    ];
                }
            }
        }

        return $orderStat;
    }

    /**
     * 获取产品对应的订单id
     * @param array $filter
     * @return array|void
     */
    public function getOrderIdsFilter($filter = [])
    {

        $model = $this->_model_product($filter);
        if ($filter['shop_type'] == 0 && $filter['current_date']) {
            $model->where('o.delivery_date', $filter['current_date']);
        }

        $orderIds = $model->distinct("op.order_id")
            ->pluck('op.order_id')
            ->toArray();

        if (empty($orderIds))
            return [];

        return $orderIds;
    }


    /**
     * 订单统计楼/层统计
     * 获取配送员的统计
     * @param $filter
     */
    public function getOrderStat($filter = null)
    {
        $orderIds = $this->_model_product($filter)->distinct("op.order_id")->pluck('op.order_id')->toArray();
        if (empty($orderIds))
            return [];

        $addressList = OrderAddress::from("order_address as oa")
            ->join("lou_address as l", "l.id", "=", "oa.province_id")
            ->join("lou_address as la", "la.id", "=", "oa.city_id")
            ->whereIn("oa.order_id", $orderIds)
            ->orderBy("l.sort", "asc")
            ->orderBy("la.sort", "asc")
            ->get(array_filter(explode(",", "oa.*,l.title as province_title,la.title as city_title")))
            ->toarray();

        if (empty($addressList))
            return null;

        $data = [];
        foreach ($addressList as $k => $v) {
            $data[$v['province_id']][$v['city_id']][$v['region_id']][] = $v;
        }

        $statList = [];
        foreach ($data as $k => $v) { //楼
            $province_title = LouAddress::query()->where(['id' => $k])->value("title");
            foreach ($v as $s1 => $v1) { //层
                $city_title = LouAddress::query()->where(['id' => $s1])->value("title");
                $city_title = is_numeric($city_title) ? ($city_title . 'F') : $city_title;

                $d = [];
                $d['province_title'] = $province_title;
                $d['city_title'] = $city_title;

                $order_amount = 0;
                $product_amount = 0;
                foreach ($v1 as $s2 => $v2) { //科室
                    $order_amount += count($v2);
                    $products = OrderProduct::query()
                        ->whereIn("order_id", get_column($v2, "order_id"))
                        ->get(["id", "type", "product_id", "amount", "order_id"])
                        ->toArray();
                    $product_amount += array_sum(get_column($products, "amount"));
                }

                $d['product_amount'] = $product_amount;
                $d['order_amount'] = $order_amount;
                $statList[] = $d;
            }
        }

        return $statList;
    }


    /**
     * 科室订单
     * @param $filter
     * @param array $condition
     * @param null $task_id
     */
    public function getKsStat($filter, $printer_id = null)
    {
        $orderList = $this->_order_model($filter)
            ->join("order_address as oa", "oa.order_id", "=", "o.id")
            ->join("lou_address as l", "l.id", "=", "oa.province_id")
            ->join("lou_address as la", "la.id", "=", "oa.city_id")
            ->orderBy("l.sort", "asc")
            ->orderBy("la.sort", "asc")
            ->get(array_filter(explode(",", "o.id,s.title as shop_title,s.open_printer_task,o.order_source,o.status,o.uid,oa.province_id,o.menu_id,oa.city_id,oa.region_id,oa.district,oa.address,l.title as province_title,la.title as city_title")))
            ->toArray();

        if (empty($orderList))
            return retFail("暂无订单");

        $orderList = ass_column($orderList, "menu_id", true);
        $printer_data = [];

        $task_data['title'] = "科室打印_" . date("hi");
        $task_data['printer_sn'] = $printer_id;
        $task_data['printer_type'] = 4;  // 科室
        $task_data['supplier_id'] = $filter['shop_id'] ?? 0;
        $task_data['amount'] = 0;
//        $task_id = D("PrinterTask")->update($task_data);

        $task_id = PrinterTask::create($task_data)->id;

        $amount = 0;
        foreach ($orderList as $menu_id => $orders) {
            $data = [];
            $menu = (new DailyMenuRepository())->getOne($menu_id);
            foreach ($orders as $sk => $sv) {
                $data[$sv['province_id']][$sv['city_id']][$sv['region_id']][] = $sv;
            }

            foreach ($data as $k => $v) {
                $province = LouAddress::query()->where(['id' => $k])->value("title");
                $province = is_numeric($province) ? ($province . '号楼') : $province;

                foreach ($v as $k1 => $v1) {
                    $city = LouAddress::query()->where(['id' => $k1])->value("title");
                    $city = is_numeric($city) ? ($city . 'F') : $city;

                    foreach ($v1 as $k2 => $v2) {
                        $amount += 1;

                        $d = [];
                        $d['order_id'] = $v2[0]['id'];
                        $d['city'] = $city;
                        $d['province'] = $province;
                        $d['order_amount'] = count($v2);
                        $d['open_printer_task'] = $v2[0]['open_printer_task'];
                        $d['region'] = LouAddress::query()->where(['id' => $k2])->value("title");
                        $d['order_amount'] = count($v2);
                        if (in_array(1, get_column($v2, 'order_source'))) {
                            $d['unpaid'] = 1;
                        }

                        $productList = OrderProduct::query()
                            ->whereIn("order_id", get_column($v2, "id"))
                            ->get(["id", "type", "product_id", "amount", "order_id", "product_title as title", "product_price as price"])
                            ->toArray();

                        $productList = ass_column($productList, "product_id", true);
                        $pData = [];
                        foreach ($productList as $pk => $pv) {
                            $pd = [
                                'amount' => array_sum(get_column($pv, "amount")),
                                'title' => $pv[0]['title'],
                                'type' => $pv[0]['type'],
                                'price' => $pv[0]['price'],
//                                'sub' => $pv[0]['skus'] ?? null,
                            ];

                            $combo_title = "";
                            if ($pv[0]['type'] == 2) { //多规格
                                $skus = OrderSku::query()->where([
                                    'order_id' => $pv[0]['order_id'],
                                    'type' => 0,
                                    'goods_id' => $pk,
                                ])->orderBy("id", "asc")
                                    ->get(['id', 'spec_item_id', 'spec_item_title', 'spec_price'])
                                    ->toArray();

                                if ($skus) {
                                    $pd['skuTxt'] = implode("、", get_column($skus, "spec_item_title"));
                                    foreach ($skus as $sk => &$sv) {
                                        $sv['spec_price'] = formatNum($sv['spec_price']);
                                    }
                                }

                                $pd['sub'] = $skus;
                                foreach ($pd['sub'] as $spk => $spv) {
                                    $combo_title .= $spv['spec_item_title'];
                                }

                            } else if ($pv[0]['type'] == 1) { // 套餐

                                $pd['sub'] = OrderSku::query()->where([
                                    'order_id' => $pv[0]['order_id'],
                                    'goods_id' => $pk,
                                    'type' => 1,
                                ])->orderBy("id", "asc")
                                    ->get(['id', 'goods_id', 'spec_id', 'spec_item_id', 'spec_item_title', 'sequence', 'amount'])
                                    ->toArray();
                                if ($pd['skus']) {
                                    $pd['skuTxt'] = implode("、", get_column($pd['skus'], "spec_item_title"));
                                }

                                $combo_title = "";
                                foreach ($pd['sub'] as $spk => $spv) {
                                    $combo_title .= $spv['spec_item_title'] . ' x' . $spv['amount'] . ' ';
                                }
                            }
                            if ($combo_title) {
                                $pd['combo_title'] = $combo_title;
                            }
                            $pData[] = $pd;
                        }

                        $d['product_amount'] = array_sum(get_column($pData, "amount"));
                        $d['products'] = $pData;
                        $d['menu_id'] = $menu_id;
                        $printer_data[] = $d;

                        (new PrinterRepository())->printerKs($d, [
                            'menu' => $menu,
                            'shop_id' => $filter['shop_id'],
                            'shop_title' => Supplier::query()->where(['id' => $menu['shop_id']])->value("title"),
                            'printer_id' => $printer_id,
                        ], $task_id);

                    }
                }
            }
        }

        if (isset($task_id) && $amount > 0) {
            PrinterTask::where('id', $task_id)->update([
                'amount' => $amount
            ]);
        }

        return retSuc("正在打印");
    }

    /**
     * 接单
     * @param array $filter
     */
    public function acceptList($filter = [], $uid = null)
    {
        $orderIds = $this->_order_model($filter)->pluck("o.id")->toArray();

        if (count($orderIds) == 0)
            return retFail("暂无符合条件的接单");

        $o_data = [];
        if ($filter['sstatus'] == 11) { //待接单
            $o_data['delivery_status'] = 10;
        } else if ($filter['sstatus'] == 12) {
            $o_data['delivery_status'] = 20;
            $o_data['deliver_status'] = 2;
        }

        $o_data['update_time'] = time();

        // 接单状态修改为已接单
        Order::query()->whereIn("id", $orderIds)->update($o_data);
        (new \App\Repositories\OrderRepository())->addLog($orderIds, $filter['delivery_status'] == 1 ? 2 : 1, $uid);

        return retSuc([], "已成功" . ($filter['sstatus'] == 12 ? '出餐' : '接单') . " (" . count($orderIds) . ")");
    }


}
